const { SerialPort } = require('serialport')
const { DelimiterParser } = require('@serialport/parser-delimiter')
// 导入日志模块
const logger = require('./log-winston.js')
// 导入sleep函数
const sleep = require('./utils/sleep.js')
// 导入bd自定义指令
const customOrder = require('./orderList/customOrder.js')
// 导入主解析器
const ps = require('./parsers/mianParser.js')
/* 全局变量定义 */
const recType = ['BDPWI', 'BDTCI', 'BDFKI', 'BDIBD']
let flagCount_bd = new Date().getTime()
let chabaErrorFlag_bd = false

/* 定时器监控串口是否打开，未打开则2秒一次打开 */
// 打开/关闭定时器启动端口-如果打开串口失败则隔2秒继续打开
let timer_bd = null
function startTimer_bd(port) {
	timer_bd = setInterval(function () {
		port.open((err) => {
			if (err) {
				console.log('再次打开串口失败!')
			} else {
				// 重新打开后这个也打开
				chabaErrorFlag_bd = true
				stopTimer_bd()
			}
		})
	}, 2000)
}
function stopTimer_bd() {
	clearInterval(timer_bd)
	timer_bd = null
}

// 获取串口列表函数->目前不支持未插串口查询COM号
async function getPortList() {
	let ports = await SerialPort.list()
	const port_bd_list = []
	ports.forEach((item) => {
		if (item.manufacturer === 'Prolific') {
			port_bd_list.push(item.path)
		}
	})
	if (port_bd_list.length < 1) {
		while (true) {
			ports = await SerialPort.list()
			ports.forEach((item) => {
				if (item.manufacturer === 'Prolific') {
					port_bd_list.push(item.path)
				}
			})
			if (port_bd_list > 0) {
				return port_bd_list
			} else {
				console.log('扫描无北斗短报文串口，正在重试...')
				await sleep(5000)
				continue
			}
		}
	}
	return port_bd_list
}

/* 初始化串口以及配置触发函数 */
async function init_port() {
	// 获取bd串口列表，打开
	const port_bd_list = await getPortList()
	if (port_bd_list.length < 1) {
		console.log(`port_bd_list的值为:${port_bd_list}`)
	}
	const port_bd = new SerialPort(
		{
			path: port_bd_list[0],
			baudRate: 115200,
			parity: 'none',
		},
		(err) => {
			if (err) {
				console.log('bd短报文串口打开失败!')
				// 如果打开失败则继续打开
				startTimer_bd(port_bd)
			} else {
				console.log('bd短报文串口打开成功!')
				// 打开成功后把标志改了
				chabaErrorFlag_bd = true
			}
		}
	)
	const parser_bd = port_bd.pipe(new DelimiterParser({ delimiter: '\r\n' }))
	parser_bd.on('data', (data) => {
		const str = data.toString()
		const head = str.split(',')[0].replace('$', '')
		const strArray = str.split(',')
		if (recType.includes(head)) {
			flagCount_bd = new Date().getTime()
			ps.mainParser(strArray, port_bd)
		}
	})
	port_bd.on('error', (err) => {
		console.log('bd捕获总体错误:', err)
	})
	// 3.注册打开串口事件，只执行一次，最先执行
	port_bd.on('open', () => {
		console.log('bd串口打开了:open事件!')
		chabaErrorFlag_bd = true
		stopTimer_bd()
	})
	return port_bd
}

async function main() {
	const port_bd = await init_port()
	// 关闭蓝牙模块和定位模块
	port_bd.write(customOrder.closePositionModule)
	port_bd.drain(() => {
		console.log('bd地面接收机-关闭定位模块')
	})
	port_bd.write(customOrder.closeBluet)
	port_bd.drain(() => {
		console.log('bd地面接收机-关闭蓝牙模块')
	})
	// 全局计数器，如果10s内没有触发port的data事件，则把所有串口和模块开启
	setInterval(function () {
		let currentTime = new Date().getTime()
		if (currentTime - flagCount_bd > 20 * 1000) {
			port_bd.write(customOrder.openShortModule)
			port_bd.drain(() => {
				console.log('bd尝试重新打开短报文模块!')
			})
			setTimeout(() => {
				port_bd.write(customOrder.openShortModuleSerial)
				port_bd.drain(() => {
					console.log('bd尝试重新打开短报文串口输出!')
				})
			}, 500)
		}
	}, 10000)
	// 心跳函数
	setInterval(async function () {
		if (!port_bd.isOpen && chabaErrorFlag_bd) {
			port_bd.open((err) => {
				if (err) {
					console.log('bd您还未插上串口,请检查线缆链接情况...')
				} else {
					console.log('bd重启串口成功...success')
					port_bd.flush((err) => {
						if (err) {
							console.log('bd清除缓存失败,请检查!')
						} else {
							console.log('bd重新插拔清除buffer缓存!')
						}
					})
				}
			})
		}
	}, 10 * 1000)
}
main()
